package org.zb.shiro.credential;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.zb.shiro.model.Permission;
import org.zb.shiro.model.Role;
import org.zb.shiro.model.User;
import org.zb.shiro.service.PersmissionService;
import org.zb.shiro.service.RoleService;
import org.zb.shiro.service.UserService;

public class CustomShiroRealm  extends AuthorizingRealm {

	@Autowired
	private UserService userService;
	
	@Autowired
	private PersmissionService permissionService;
	
	@Autowired
	private RoleService roleService;
	
	/**
	 * stored authorization data (roles, permissions, etc)
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		
		Long userId = (Long) principals.getPrimaryPrincipal();
		
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		
		List<Role> roles = roleService.findByUserId(userId);
		if (roles != null) {

			Set<String> roleNames = new HashSet<String>();
			List<Long> roleIds = new ArrayList<Long>();
			for(Role role : roles) {
				roleNames.add(role.getName());
				roleIds.add(role.getId());
			}
			authorizationInfo.setRoles(roleNames);
			
			List<Permission> permissions = permissionService.findByRoleIds(roleIds);
			if (permissions != null) {

				Set<String> stringPermissions = new HashSet<String>();
				for(Permission permission : permissions ) {
					stringPermissions.add(permission.getName());
				}
				authorizationInfo.setStringPermissions(stringPermissions);
			}
		}
		
		return authorizationInfo;
	}
	
	/**
	 *  stored account information
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authcToken) throws AuthenticationException {
		String username = (String) authcToken.getPrincipal();
		User user = userService.findByUsername(username);
        if (user == null) {
            // 用户名不存在抛出异常
            throw new UnknownAccountException();
        }
        if (user.getStatus() == 1) {
            // 用户被管理员锁定抛出异常
            throw new LockedAccountException();
        }
        SimpleAuthenticationInfo authenticationInfo = 
        		new SimpleAuthenticationInfo(user.getId(),user.getPassword(), getName());
        return authenticationInfo;
	}
}